--unit 扩展 group
---@class mGroup
local mGroup = {
    type = 'module',
    module = 'group',

    regList = {},
}
mGroup.__index = mGroup
---@class cGroup
---@field units unit[]
local cGroup = {
    type = 'class',
    class = 'group',

}
cGroup.__index = cGroup

---@ 来自 unit:init 的事件响应
local reg = unit:event_any( '单位-初始化',function (event, params)
    local unit = params.unit

    mGroup:reg( unit )
end)

---@ 来自 unit死亡 的事件响应
local unReg = unit:event_any( '单位-死亡',function (event, params)
    local unit = params.death
    mGroup:unReg( unit )
end)

---@private 注册进单位组模块
---@param u unit
function mGroup:reg(u)
    if self:reged(u) then return end
    local list = self.regList
    table_insert( list, u )
    list[ u ] = true
end

---@private 单位是否注册过
---@param u unit
---@return bool
function mGroup:reged(u)
    if self.regList[ u ] then
        return true
    end
    return false
end


---@private 取消注册单位 单位组模块
---@param u unit
---@return bool
function mGroup:unReg(u)
    if not self:reged(u) then return end
    local list = self.regList
    for index, obj in ipairs(list) do
        if u == obj then
            list [  obj  ] = nil
            table.remove( list, index )
            list[0] = list[0] - 1
            return true
        end
    end
    return false
end

---@ 对区域内的单位创建一个单位组
---@param rct rect
---@param filter fun( u:unit ):bool 返回true 表示单位是你所需要的
---@return group
function mGroup:newByRect( rct, filter )
    local g = self:new()
    self:enum( function ( u )
        local x, y = u:getX(), u:getY()

        if not rct:isCoordInRect( x, y ) then
            return --单位不在矩形区域中
        end

        if filter then
            if not filter( u ) then
                return -- filter 不通过
            end
        end

        g:addUnit( u ) --入选单位

    end )

    return g
end

---@ 新建空单位组
---@return group
function mGroup:new()
    ---@class group : cGroup
    local g = {
        type = 'group',
        units = {}, --单位组中所有单位

    }
    setmetatable( g, cGroup )
    return g
end


---@private 枚举所有注册过的单位
---@param callback fun( u:unit ):bool 返回true 表示退出枚举
function mGroup:enum( callback )
    local list = self.regList
    local i = 1
    local u = list[i]

    --暴力枚举直至nil
    while u do

        if callback( u ) then
            return
        end

        i = i + 1
        u = list[i]
    end

end

--- 添加一个单位进入单位组
---@param u unit
function cGroup:addUnit( u )
    if self:unitExist( u ) then
        return --已存在单位组内
    end
    table_insert( self.units, u )
    self.units [ u ] = true
end

--- 判断单位是否在单位组中
---@param u unit
---@return bool
function cGroup:unitExist( u )
    if self.units [ u ] then
        return true
    end
    return false
end

--- 从单位组中移除单位
---@param u unit
---@return bool
function cGroup:removeUnit( u )
    if not self:unitExist( u ) then
        return false--找不到该单位
    end
    local  list  =  self.units
    list[u] = nil
    for index, obj in ipairs(list) do
        if obj == u then
            table.remove( list, index )
            list[0] = list[0] - 1
            return true
        end
    end
    return true
end

--- 枚举所有注册过的单位
---@param callback fun( u:unit ):bool 返回true 表示退出枚举
function cGroup:enum( callback )
    local list = self.units
    local i = 1
    local u = list[i]

    --暴力枚举直至nil
    while u do
        --单位已销毁
        if u.class ~= 'unit' then
            table.remove( list, i )
            goto next
        end

        if callback( u ) then
            return
        end

        --被删除则不增加索引值
        if u == list[i] then
            i = i + 1
        end
        ::next::
        u = list[i]
    end

end

return mGroup